<template>
    <!-- 工作台配置 -->
    <div class="container h-100">
        <div class="top space-between">
            <div class="v-center cursor-pointer" @click="back">
                <el-icon><ArrowLeft /></el-icon> <span>返回</span>
            </div>

            <div class="title">
                <span class="font-bold mr-2">{{ workbench.name }}</span>
                <el-text v-if="changed" type="warning">已修改</el-text>
                <el-text v-else-if="workbench.status != 'published'" type="danger">未发布</el-text>
            </div>

            <div class="buttons v-center">
                <div class="v-center mr-4">
                    <span class="mr-2">显示网格</span>
                    <el-switch v-model="showGrid" class="switch"></el-switch>
                </div>
                <el-button type="primary" icon="Checked" plain @click="save()">保存</el-button>
                <el-button type="success" icon="Check" plain @click="publish">发布</el-button>
            </div>
        </div>

        <div class="content" :class="{ grid: showGrid }">
            <div class="left bg-main p-2 pt-0">
                <el-tabs>
                    <el-tab-pane>
                        <template #label>
                            <span class="px-2 v-center">
                                <el-icon><Menu /></el-icon>
                                <span>组件</span>
                            </span>
                        </template>
                        <cmps @select="addCmp" />
                    </el-tab-pane>
                    <el-tab-pane>
                        <template #label>
                            <span class="px-2 v-center">
                                <el-icon><Files /></el-icon>
                                <span>页面结构</span>
                            </span>
                        </template>
                        <CmpTree v-model="workbench.config" @currentChange="selectCmp" />
                    </el-tab-pane>
                </el-tabs>
            </div>

            <div class="center m-3 p-1">
                <div class="cmps">
                    <wrapper
                        v-for="cmp in workbench.config.children"
                        :cmp="cmp"
                        :key="cmp.id"
                        @select="selectCmp"
                        class="cmp"
                        @contextmenu.prevent="handleContextMenu($event, cmp)"
                        @change="configChanged"
                    />
                </div>
            </div>

            <div class="right bg-main py-3 px-1">
                <div class="page-title mb-2">组件配置</div>
                <ConfigPanel v-if="currentCmp" v-model="currentCmp" :key="currentCmp.id" @change="configChanged" />
            </div>
        </div>

        <CmpMenus v-model="workbench.config" ref="menuRef" @change="configChanged" />
    </div>
</template>
<script setup>
import { onMounted, onUnmounted, reactive } from "vue";
import * as _ from "lodash";
import { v4 } from "uuid";
import ConfigPanel from "./config/config.vue";
import { useRoute, useRouter } from "vue-router";
import wrapper from "./wrapper.vue";
import cmps from "./cmps.vue";
import defConfig from "./example/default.js";
import CmpMenus from "./cmp-menus.vue";
import CmpTree from "./cmp-tree.vue";

const route = useRoute();
const id = computed(() => route.params.id);
const workbench = ref({
    config: {
        config: {},
        children: [],
    },
});
const currentCmp = ref();
const router = useRouter();
const showGrid = ref(false);
const menuRef = ref();
const changed = ref(false);

onMounted(() => {
    app.https.get("/sys/workbench/detail/" + id.value).then((resp) => {
        if (!resp) {
            app.error("工作台不存在");
            back();
            return;
        }
        if (!resp.config) {
            resp.config = _.cloneDeep(defConfig);
        }

        workbench.value = resp;
    });
    window.addEventListener("beforeunload", exitCheck);
});

onUnmounted(() => {
    window.removeEventListener("beforeunload", exitCheck);
});

function exitCheck(e) {
    if (changed.value) {
        e && e.preventDefault();
        e.returnValue = "";
        return "配置未保存，请确认是否离开";
    }
}

function addCmp(cmp) {
    cmp = _.cloneDeep(cmp);
    cmp.id = v4();
    workbench.value.config.children.push(cmp);
}

function selectCmp(cmp) {
    currentCmp.value = cmp;
}

function back() {
    if (changed.value) {
        app.confirm("配置未保存，离开将导致未保存配置丢失，是否确认？").then(() => {
            router.back();
        });
    } else {
        router.back();
    }
}

function save(isPublish = false) {
    let status = isPublish ? "published" : "editing";
    app.https
        .put("/sys/workbench/update", {
            ...workbench.value,
            status,
        })
        .then(() => {
            app.success();
            changed.value = false;
            workbench.value.status = status;
        });
}

function publish() {
    workbench.value.publishedConfig = _.cloneDeep(workbench.value.config);
    save(true);
}

// 显示右键弹出菜单
function handleContextMenu(e, cmp) {
    e.preventDefault();
    menuRef.value.show(e, cmp);
}

function configChanged() {
    changed.value = true;
}
</script>

<style lang="scss" scoped>
.container {
    background: var(--sub_bg_color);
    display: grid;
    grid-template-rows: 48px 1fr;
    padding-bottom: 8px;
}

.top {
    display: flex;
    align-items: center;
    padding: 0 16px;
    background: var(--main_bg_color);
    border-bottom: 1px solid var(--sub_border_color);
}

.content {
    --border_color: var(--main_border_color);
    display: grid;
    grid-template-columns: 240px 1fr 300px;

    .center {
        box-sizing: border-box;
        overflow-y: auto;
        overflow-x: hidden;

        .cmps {
            position: relative;
            box-sizing: border-box;
            height: 100%;

            .cmp {
                position: absolute;
                box-sizing: border-box;

                &:hover {
                    box-shadow: 0 0 5px var(--primary_color);
                }
            }
        }
    }
}

.grid {
    background-image: linear-gradient(to right, var(--border_color) 1px, transparent 1px), linear-gradient(to bottom, var(--border_color) 1px, transparent 1px);
    background-size: 20px 20px;
    background-position: 0 0;
}

:deep() {
    .left .el-tabs__header .el-tabs__item {
        padding: 0;
    }
}
</style>
